/*********************
* Author:Dzlua
* QQ:505544956
* time:2016/11/28
*/
#include "LuaMgr.h"

#ifdef EDUI_USE_LUAPLUS

#include "../lua/LuaHelper.h"
#include "../utilities/Log.h"
#include "../interface/IEngine.h"

EDUI_NAMESPACE_BEGIN

#define LuaStatePtr(L) ((LuaState*)(L))

LuaMgr::LuaMgr() : m_lua(0)
{}

LuaMgr::~LuaMgr()
{
    this->Quit();
}

bool LuaMgr::Init()
{
    if (m_lua) return true;
    m_lua = LuaState::Create(true);
    if (!m_lua) return false;

    LuaHelperNS::RegisterLuaAll(LuaStatePtr(m_lua));

    return true;
}

bool LuaMgr::DoFile(const char* file)
{
    if (0 == LuaStatePtr(m_lua)->DoFile(file)) return true;
    LuaStack args(LuaStatePtr(m_lua));
    if (args[1].IsString()){
        IEnginePtr->SetError(args[1].GetString());
    }
    return false;
}

void LuaMgr::Quit()
{
    if (m_lua){
        LuaState::Destroy(LuaStatePtr(m_lua));
        m_lua = 0;
    }
}

void* LuaMgr::GetLuaState() const
{
    return m_lua;
}

//add the data to saved Luaclass objects
void LuaMgr::Add(const char* key, void* data)
{
    LuaState *L = LuaStatePtr(m_lua);
    //metatable
    LuaObject meta = LuaHelperNS::GetFromMetas(L, key);
    if (!meta.IsTable()) return;
    if (!meta["__NewCObj__"].IsFunction()) return;
    //new a cluaobj
    LuaFunction<void*> funNewObj(meta["__NewCObj__"]);
    LuaClassBase *pCObj = (LuaClassBase*)funNewObj(data);
    if (!pCObj) return;
    //create a table and add to saved Luaclss objects.
    LuaObject obj = LuaHelperNS::AddToObjs(L, data);
    //save CObj.
    LuaHelperNS::SetCObject(obj, pCObj);
    //set metatable.
    obj.SetMetatable(meta);
}

//remove the data from saved Luaclass objects
void LuaMgr::Remove(void* data)
{
    LuaState *L = LuaStatePtr(m_lua);
    //get the cluaobj.
    LuaObject obj = LuaHelperNS::GetFromObjs(L, data);
    //get the CObj.
    LuaClassBase *pCObj = LuaHelperNS::GetCObject(obj);
    if (pCObj) pCObj->Release();
    LuaHelperNS::RemoveFromObjs(L, data);
}

//objects do event
void LuaMgr::DoEvent(void* data, const char* eventname)
{
    LuaState *L = LuaStatePtr(m_lua);
    LuaObject obj = LuaHelperNS::GetEventFromObjs(L, data, eventname);
    if (!obj.IsFunction()) return;
    LuaFunctionVoid evtFun(obj);
    evtFun(LuaHelperNS::GetFromObjs(L, data));
}

//objects do timer
Uint32 LuaMgr::DoTimer(void* key, TimerID id, Uint32 interval)
{
    LuaState *L = LuaStatePtr(m_lua);
    LuaObject obj = LuaHelperNS::GetTimerFromObjs(L, key, id);
    if (!obj.IsFunction()) return interval;
    LuaFunction<Uint32> evtFun(obj);
    return evtFun(id, interval, LuaHelperNS::GetFromObjs(L, key));
}

#undef LuaStatePtr

EDUI_NAMESPACE_END

#endif
